/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.spi.jsonser.entity;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.inspur.edp.cef.entity.changeset.AbstractModifyChangeDetail;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.changeset.ModifyChangeDetail;
import com.inspur.edp.cef.spi.extend.entity.ICefAddedChildEntityExtend;
import com.inspur.edp.cef.spi.extend.entity.ICefEntityExtend;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.AbstractCefChangeSerializer;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.AbstractCefDataSerItem;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class AbstractEntityChangeSerializer extends AbstractCefChangeSerializer
{
	protected String nodeCode;
	protected boolean isRoot;

	public AbstractEntityChangeSerializer(String nodeCode, boolean isRoot, java.util.List<AbstractEntitySerializerItem> serializers)
	{
		super(null);
		List<AbstractCefDataSerItem> list=new ArrayList<AbstractCefDataSerItem>();
		for (AbstractEntitySerializerItem item:serializers
			 ) {
			list.add(item);
		}
		super.serializers=list;
		this.nodeCode = nodeCode;
		this.isRoot = isRoot;
	}



		///#region 序列化
	@Override
	protected void writeModifyJson(JsonGenerator jsonGenerator, AbstractModifyChangeDetail detail, SerializerProvider serializerProvider)	throws IOException
	{
		jsonGenerator.writeFieldName(DataId);
		jsonGenerator.writeString(detail.getDataID());
		super.writeModifyJson(jsonGenerator, detail, serializerProvider);
		//多语 udt的是ValueObjModifyChangeDetail
		if(detail instanceof ModifyChangeDetail){
			writeModifyChildJson(jsonGenerator, ((ModifyChangeDetail)detail).getChildChanges(), serializerProvider);
		}
	}

	private void writeModifyChildJson(JsonGenerator jsonGenerator, java.util.Map<String, java.util.Map<String, IChangeDetail>> childChanges, SerializerProvider serializerProvider) throws IOException {
		for (Map.Entry<String,Map<String,IChangeDetail>> child : childChanges.entrySet())
		{
			writeChildDetailJson(jsonGenerator, child.getKey(), child.getValue(), serializerProvider);
		}
	}

	private void writeChildDetailJson(JsonGenerator jsonGenerator, String nodeCode, java.util.Map<String, IChangeDetail> childChanges, SerializerProvider serializerProvider) throws IOException {
		Object[] changes = childChanges.values().toArray();

		writeChildDetailJson(jsonGenerator, nodeCode, changes, serializerProvider);
	}

	private void writeChildDetailJson(JsonGenerator jsonGenerator, String nodeCode, Object[] childDetails, SerializerProvider serializerProvider) throws IOException {
		AbstractEntityChangeSerializer childConvertor = innerGetChildConvertor(nodeCode);
		if (childConvertor == null) {
			childConvertor = getDefaultChildChangeSerializer();
		}
		jsonGenerator.writeFieldName(getPropertyNameByChildNode(nodeCode));

		jsonGenerator.writeStartArray();

		for (Object changeDetail : childDetails)
		{
			childConvertor.writeJson((IChangeDetail) changeDetail,jsonGenerator, serializerProvider);
		}
		jsonGenerator.writeEndArray();
	}

	protected AbstractEntityChangeSerializer getDefaultChildChangeSerializer(){
		return new CommonEntityChangeSerializer();
	}

	private String getPropertyNameByChildNode(String nodeCode)
	{
		return String.format("%1$s%2$s", StringUtils.toCamelCase(nodeCode), "s");
	}

	private AbstractEntityChangeSerializer innerGetChildConvertor(String nodeCode){
		for(Object item : getExtendList()) {
			List<ICefAddedChildEntityExtend> addedChilds = ((ICefEntityExtend)item).getAddedChilds();
			if(addedChilds == null){
				continue;
			}
			for(ICefAddedChildEntityExtend addedChild : addedChilds){
				if(addedChild.getNodeCode().equals(nodeCode)){
					return (AbstractEntityChangeSerializer)addedChild.getChangeSerializer();
				}
			}
		}
		return getChildEntityConvertor(nodeCode);
	}

	/** 
	 获取子节点转换器。
	 
	 @param nodeCode 节点编号
	 @return 得到的子节点转换器
	*/
	protected abstract AbstractEntityChangeSerializer getChildEntityConvertor(String nodeCode);

		///#endregion


		///#region 反序列化







		///#endregion
}
